package com.xinggq.user.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinggq.common.context.UserContext;
import com.xinggq.common.enums.EnableEnum;
import com.xinggq.common.exception.AbstractCommonException;
import com.xinggq.common.page.PageCondition;
import com.xinggq.user.service.dto.role.RoleCreateRequest;
import com.xinggq.user.service.dto.role.RolePageRequest;
import com.xinggq.user.service.dto.role.RoleUpdateRequest;
import com.xinggq.user.service.dto.role.RoleVO;
import com.xinggq.user.service.entity.SysRoleEntity;
import com.xinggq.user.service.mapper.SysRoleMapper;
import com.xinggq.user.service.service.RoleService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;

/**
 * 角色服务实现类
 *
 * @author system
 * @since 2025-01-10
 */
@Service
@Slf4j
@AllArgsConstructor
public class RoleServiceImpl implements RoleService {

  private final SysRoleMapper roleMapper;

  @Override
  @Transactional(rollbackFor = Exception.class)
  public RoleVO createRole(RoleCreateRequest request) {
    log.info("创建角色，请求参数: {}", request);

    // 校验角色编码唯一性
    validateRoleCodeUnique(request.getRoleCode(), null);

    // 校验角色名称唯一性
    validateRoleNameUnique(request.getRoleName(), null);

    // 构建角色实体
    SysRoleEntity roleEntity = buildRoleEntity(request);

    // 保存角色
    roleMapper.insert(roleEntity);

    log.info("角色创建成功，角色ID: {}", roleEntity.getId());
    return RoleVO.fromEntity(roleEntity);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public RoleVO updateRole(RoleUpdateRequest request) {
    log.info("更新角色，请求参数: {}", request);

    // 检查角色是否存在
    SysRoleEntity existingRole = roleMapper.selectById(request.getId());
    if (existingRole == null || EnableEnum.D.getCode().equals(existingRole.getStatus())) {
      throw AbstractCommonException.dataNotFound("角色");
    }

    // 校验角色编码唯一性
    validateRoleCodeUnique(request.getRoleCode(), request.getId());

    // 校验角色名称唯一性
    validateRoleNameUnique(request.getRoleName(), request.getId());

    // 更新角色信息
    existingRole.setRoleName(request.getRoleName())
        .setRoleCode(request.getRoleCode())
        .setDescription(request.getDescription())
        .setIsSystem(request.getIsSystem())
        .setSortOrder(request.getSortOrder())
        .setUpdatedBy(request.getUpdatedBy())
        .setUpdatedAt(LocalDateTime.now());

    roleMapper.updateById(existingRole);

    log.info("角色更新成功，角色ID: {}", existingRole.getId());
    return RoleVO.fromEntity(existingRole);
  }

  @Override
  public RoleVO getRoleDetailById(Long roleId) {
    log.info("获取角色详情，角色ID: {}", roleId);
    // 通过ID查询角色信息
    SysRoleEntity roleEntity = roleMapper.selectById(roleId);
    if (roleEntity == null || EnableEnum.D.getCode().equals(roleEntity.getStatus())) {
      throw AbstractCommonException.dataNotFound("角色");
    }

    return RoleVO.fromEntity(roleEntity);
  }

  @Override
  public RoleVO getRoleDetailByCode(String roleCode) {
    // 通过ID查询角色信息
    LambdaQueryWrapper<SysRoleEntity> roleEntityWrapper = new LambdaQueryWrapper<>();
    roleEntityWrapper.eq(SysRoleEntity::getRoleCode, roleCode);
    SysRoleEntity roleEntity = roleMapper.selectOne(roleEntityWrapper);
    if (roleEntity == null || EnableEnum.D.getCode().equals(roleEntity.getStatus())) {
      throw AbstractCommonException.dataNotFound("角色");
    }

    return RoleVO.fromEntity(roleEntity);
  }

  @Override
  public IPage<RoleVO> pageQuery(PageCondition<RolePageRequest> pageCondition) {
    log.info("分页查询角色，查询条件: {}", pageCondition);

    RolePageRequest request = pageCondition.getQueryDto();

    // 构建查询条件
    LambdaQueryWrapper<SysRoleEntity> queryWrapper = new LambdaQueryWrapper<>();

    // 租户ID过滤
    if (request != null && request.getTenantId() != null) {
      queryWrapper.eq(SysRoleEntity::getTenantId, UserContext.getCurrentTenantId());
    }

    // 角色名称模糊查询
    if (request != null && StringUtils.hasText(request.getRoleName())) {
      queryWrapper.like(SysRoleEntity::getRoleName, request.getRoleName());
    }

    // 角色编码模糊查询
    if (request != null && StringUtils.hasText(request.getRoleCode())) {
      queryWrapper.like(SysRoleEntity::getRoleCode, request.getRoleCode());
    }

    // 角色描述模糊查询
    if (request != null && StringUtils.hasText(request.getDescription())) {
      queryWrapper.like(SysRoleEntity::getDescription, request.getDescription());
    }

    // 是否系统角色过滤
    if (request != null && request.getIsSystem() != null) {
      queryWrapper.eq(SysRoleEntity::getIsSystem, request.getIsSystem());
    }

    // 状态过滤
    if (request != null && request.getStatus() != null) {
      queryWrapper.eq(SysRoleEntity::getStatus, request.getStatus());
    } else {
      // 默认不查询已删除的角色
      queryWrapper.ne(SysRoleEntity::getStatus, EnableEnum.D.getCode());
    }

    // 排序
    queryWrapper.orderByAsc(SysRoleEntity::getSortOrder)
        .orderByDesc(SysRoleEntity::getCreatedAt);

    // 分页查询
    Page<SysRoleEntity> page = new Page<>(pageCondition.getPageNum(), pageCondition.getPageSize());
    IPage<SysRoleEntity> rolePage = roleMapper.selectPage(page, queryWrapper);

    // 转换为VO
    return rolePage.convert(RoleVO::fromEntity);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public boolean deleteRole(Long roleId) {
    log.info("删除角色，角色ID: {}", roleId);

    // 检查角色是否存在
    SysRoleEntity roleEntity = roleMapper.selectById(roleId);
    if (roleEntity == null || EnableEnum.D.getCode().equals(roleEntity.getStatus())) {
      throw AbstractCommonException.dataNotFound("角色");
    }

    // 逻辑删除
    roleEntity.setStatus(EnableEnum.D.getCode())
        .setUpdatedAt(LocalDateTime.now());

    int result = roleMapper.updateById(roleEntity);

    log.info("角色删除成功，角色ID: {}", roleId);
    return result > 0;
  }

  /**
   * 校验角色编码唯一性
   */
  private void validateRoleCodeUnique(String roleCode, Long excludeId) {
    LambdaQueryWrapper<SysRoleEntity> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(SysRoleEntity::getRoleCode, roleCode)
        .ne(SysRoleEntity::getStatus, EnableEnum.D.getCode());

    if (excludeId != null) {
      queryWrapper.ne(SysRoleEntity::getId, excludeId);
    }

    long count = roleMapper.selectCount(queryWrapper);
    if (count > 0) {
      throw AbstractCommonException.dataExists("角色编码");
    }
  }

  /**
   * 校验角色名称唯一性
   */
  private void validateRoleNameUnique(String roleName, Long excludeId) {
    LambdaQueryWrapper<SysRoleEntity> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(SysRoleEntity::getRoleName, roleName)
        .ne(SysRoleEntity::getStatus, EnableEnum.D.getCode());

    if (excludeId != null) {
      queryWrapper.ne(SysRoleEntity::getId, excludeId);
    }

    long count = roleMapper.selectCount(queryWrapper);
    if (count > 0) {
      throw AbstractCommonException.dataExists("角色名称");
    }
  }

  /**
   * 构建角色实体
   */
  private SysRoleEntity buildRoleEntity(RoleCreateRequest request) {
    LocalDateTime now = LocalDateTime.now();

    return new SysRoleEntity()
        .setTenantId(UserContext.getCurrentTenantId())
        .setRoleName(request.getRoleName())
        .setRoleCode(request.getRoleCode())
        .setDescription(request.getDescription())
        .setStatus(EnableEnum.Y.getCode())
        .setSortOrder(request.getSortOrder() != null ? request.getSortOrder() : 0)
        .setCreatedBy(request.getCreatedBy())
        .setCreatedAt(now)
        .setUpdatedBy(UserContext.getCurrentUserId())
        .setUpdatedAt(now);
  }
}